package com.lanlion.portlet;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lanlion.porlet.common.WechatMicroShopView;
import com.lanlion.porlet.common.WechatMicroShopEntity;
import com.lanlion.portlet.http.HttpHelper;
import com.lanlion.portlet.http.HttpResult;
import com.lanlion.portlet.http.HttpSSLHelper;
import com.lanlion.portlet.tool.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * 服务商模式下，小微商户申请开通微信商户工具类
 */
public class WechatMicroShopUtils {

    Logger logger = LoggerFactory.getLogger(WechatMicroShopUtils.class);

    private static WechatMicroShopUtils wechatMicroShopUtils;
    private String appid; //服务商绑定的微信APPid
    private String certPath; //微信服务商证书路径,.p12文件路径
    private String mchid; //微信服务商商户号
    private String paymentKey; //微信服务商支付秘钥
    private String apiKey; //微信服务商APIv3秘钥
    private HttpSSLHelper httpSSLHelper;

    private WechatMicroShopUtils(String certPath, String mchid, String paymentKey, String apiKey, String appid){
        this.certPath = certPath;
        this.mchid = mchid;
        this.paymentKey = paymentKey;
        this.apiKey = apiKey;
        this.appid = appid;
        httpSSLHelper = new HttpSSLHelper(certPath,mchid);
    }

    public static WechatMicroShopUtils getInstance(String certPath, String mchid, String paymentKey, String apiKey, String appid){
        if(wechatMicroShopUtils == null ){
            wechatMicroShopUtils = new WechatMicroShopUtils(certPath,mchid,paymentKey,apiKey,appid);
        }
        return wechatMicroShopUtils;
    }


    /**
     * 获取API证书对象
     * @return
     * @throws Exception
     */
    private  String getCertFicaties()throws Exception{
        String url = WechatConstants.GET_CERTFICATES;
        Map<String,String> params = new HashMap<>();
        params.put("mch_id", this.getMchid());
        params.put("nonce_str", StringHelper.getRandomNumber(32));
        params.put("sign_type", WechatConstants.HMACSHA256);
        String signString = WechatEncryptHelper.getSignBySHA256(params,this.getPaymentKey());
        params.put("sign", signString);
        HttpResult result = HttpHelper.getHttpFactory().doPost4XML(url, StringHelper.mapToXml(params));
        Map resMap = StringHelper.xmlToMap(result.getResult());
        String res = resMap.get("certificates").toString();
        logger.info("getCertFicaties获取文件内容："+res);
        return res;
    }

    /**
     * 获取证书序列号
     * @return
     * @throws Exception
     */
    public  String getCERTSN()throws Exception{
        JSONObject certificateArray = JSONObject.parseObject(getCertFicaties());
        JSONArray dataArray = certificateArray.getJSONArray("data");
        JSONObject sertObject = dataArray.getJSONObject(0);
        String certSN =sertObject.getString("serial_no");
        logger.info("获取的微信证书编码为："+certSN);
        return certSN;
    }

    /**
     * 获取微信证书解密字符串
     * @return
     * @throws Exception
     */
    public  String getWXCert()throws Exception {
        //敏感信息证书生成所需参数

        JSONObject encryCertificateJSON = JSONObject.parseObject(getCertFicaties());
        JSONObject encryptCertificate = encryCertificateJSON.getJSONArray("data").getJSONObject(0);
        JSONObject certificate = encryptCertificate.getJSONObject("encrypt_certificate");
        String nonce = certificate.getString("nonce");
        String associatedData = certificate.getString("associated_data");
        //要被解密的证书字符串
        String cipherText = certificate.getString("ciphertext");
        String wechatpayCert = null;
        try {
            wechatpayCert = WechatEncryptHelper.aesgcmDecrypt(associatedData, nonce, cipherText,apiKey);
        } catch (Exception e) {
            logger.error("获取微信证书解密字符串出错："+e.getMessage());
        }
        logger.info("微信证书解密字符串："+wechatpayCert);
        return wechatpayCert;
    }




    /**
     * API请求说明：https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_2
     * @param entity 小微开店实体类，详细字段见实体说明
     * @return 正常是返回applyId ,错误时返回NULL
     * @throws Exception
     *
     */
    public String createMicroShop(WechatMicroShopEntity entity)throws Exception {
        String url = WechatConstants.SEND_MICROSHOP;
        String cert = this.getWXCert();
        Map<String,String> params = new HashMap<>();
        params.put("version",WechatConstants.MICROAPI_VERSION);
        params.put("cert_sn",this.getCERTSN());
        params.put("mch_id",this.getMchid());
        params.put("nonce_str", StringHelper.getRandomNumber(32));
        params.put("sign_type", WechatConstants.HMACSHA256);

        //提交申请的店铺Id
        params.put("business_code", entity.getShopId());
        //店铺申请人的身份证证明
        params.put("id_card_copy", entity.getIdCardCopy());
        //店铺申请人身份证反面
        params.put("id_card_national", entity.getIdCardNational());

        //申请人真实姓名(加密方法详见敏感信息加密说明)
        params.put("id_card_name", WechatEncryptHelper.rsaEncrypt(entity.getIdcarName(),cert));
        //申请人身份证号码
        params.put("id_card_number", WechatEncryptHelper.rsaEncrypt(entity.getIdcardNum(),cert));
        //身份证有效期限,示例格式["1970-01-01","长期"]
        params.put("id_card_valid_time", entity.getValidTime());
        //银行卡姓名
        params.put("account_name", WechatEncryptHelper.rsaEncrypt(entity.getAccountName(),cert));

        //开户银行：eg:工商银行
        params.put("account_bank", entity.getBankName());

        //开户银行省市编码
        params.put("bank_address_code",entity.getBankAddressCode());

        //银行账号
        params.put("account_number",WechatEncryptHelper.rsaEncrypt(entity.getBankNumber(),cert));

        //店铺名称
        params.put("store_name",entity.getStoreName());
        //门店省市编码
        params.put("store_address_code",entity.getStoreAddressCode());
        //门店街道名称
        params.put("store_street",entity.getStoreStreet());
        //门店门口照片
        params.put("store_entrance_pic",entity.getStoreEntrancePic());
        //店内环境照片
        params.put("indoor_pic",entity.getIndoorPic());
        //商户简称
        params.put("merchant_shortname",entity.getMerchantShortname());
        //客服电话
        params.put("service_phone",entity.getServicePhone());
        //售卖商品/提供服务描述
        params.put("product_desc",  entity.getProductDesc());
        //费率:不可以随意设置，微信提供可以设定的值
        params.put("rate",  entity.getRate());
        //超级管理员姓名
        params.put("contact",  WechatEncryptHelper.rsaEncrypt(entity.getContact(),cert));
        //手机号码
        params.put("contact_phone",  WechatEncryptHelper.rsaEncrypt(entity.getContactPhone(),cert));

        String signString = WechatEncryptHelper.getSignBySHA256(params,this.getPaymentKey());
        logger.info("签名结果："+signString);
        params.put("sign", signString);
        String httpResult = this.getHttpSSLHelper().doPost4XML(url,StringHelper.mapToXml(params)).getResult();
        logger.info("小微商户申请开户HTTP结果："+httpResult);
        Map<String,String> resultMap = StringHelper.xmlToMap(httpResult);
        if(resultMap.containsKey("return_code")){
            if(resultMap.get("return_code").equals(WechatConstants.SUCCESS)){
                if(resultMap.containsKey("result_code")){
                    if(resultMap.get("result_code").equals(WechatConstants.SUCCESS)){
                        return resultMap.containsKey("applyment_id")?resultMap.get("applyment_id"):null;
                    }

                }
            }
        }

        return null;
    }




    /**
     * 小微开店状态查询
     * 详情API说明：https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_3
     * @param businessNo 申请订单号，如无特殊说明一般为商户ID
     * @param applymentId 小微开店申请订单号
     * @return
     */
    public WechatMicroShopView getMicroShopState(String businessNo, String applymentId)throws Exception{

        WechatMicroShopView wechatMicroShopView = null;
        String url = WechatConstants.GETMICRO_STATE;
        Map<String,String> params = new HashMap<>();
        params.put("version","1.0");
        params.put("mch_id",this.getMchid());
        params.put("nonce_str",StringHelper.getRandomString(32));
        params.put("sign_type",WechatConstants.HMACSHA256);
        params.put("applyment_id",applymentId);
        params.put("business_code",businessNo);

        //获取加密签名，仅支持HMACSHA256
        String signString = WechatEncryptHelper.getSignBySHA256(params,this.paymentKey);
        params.put("sign", signString);

        String httpResult = this.getHttpSSLHelper().doPost4XML(url,StringHelper.mapToXml(params)).getResult();
        logger.info("小微商户查询进度请求结果："+httpResult);
        Map<String,String> resultMap = StringHelper.xmlToMap(httpResult);

        if(resultMap.containsKey("return_code")){
            if(resultMap.get("return_code").equals(WechatConstants.SUCCESS)){
                if(resultMap.containsKey("result_code")){
                    if(resultMap.get("result_code").equals(WechatConstants.SUCCESS)){

                        wechatMicroShopView.setResultCode(WechatConstants.SUCCESS);
                        wechatMicroShopView.setReturnCode(WechatConstants.SUCCESS);
                        wechatMicroShopView.setApplymentState(resultMap.get("applyment_state"));
                        wechatMicroShopView.setAuditDetail(resultMap.get("audit_detail"));
                        wechatMicroShopView.setSignUrl(resultMap.get("sign_url"));
                        wechatMicroShopView.setSubMchId(resultMap.get("sub_mch_id"));

                    }
                }
            }
        }
        return wechatMicroShopView;
    }


    /**
     * 配置小微商户支付目录
     * @param subMchid 小微商户申请的商户ID
     * @param jsapiPath 小微商户需要配置的支付目录
     * @return
     * @throws Exception
     */
    public WechatMicroShopView configMicroShopPayDirectory(String subMchid,String jsapiPath)throws Exception{
        WechatMicroShopView wechatMicroShopView = null;
        String url = WechatConstants.CONFIG_MICROSHOP_PAYMENT;
        Map<String,String> params = new HashMap<>();
        params.put("appid",this.getAppid());
        params.put("mch_id",this.getMchid());
        params.put("sub_mch_id",subMchid);
        params.put("jsapi_path",jsapiPath);
        String signString = WechatEncryptHelper.getSignByMD5(params,this.getPaymentKey());
        params.put("sign", signString);
        String httpResult = this.getHttpSSLHelper().doPost4XML(url, StringHelper.mapToXml(params)).getResult();
        logger.info("小微商户请求配置支付目录结果："+httpResult);
        Map<String,String> resultMap = StringHelper.xmlToMap(httpResult);
        if(null!=resultMap && resultMap.keySet().contains("return_code")&&resultMap.get("return_code").equals(WechatConstants.SUCCESS)){
            wechatMicroShopView = new WechatMicroShopView();
            wechatMicroShopView.setReturnCode(WechatConstants.SUCCESS);
            wechatMicroShopView.setResultCode(resultMap.get("result_code"));
            if(resultMap.get("result_code").equals(WechatConstants.FAIL)){
                wechatMicroShopView.setErrCode(resultMap.get("err_code"));
                wechatMicroShopView.setErrCodeDes(resultMap.get("err_code_des"));
            }

        }
        return wechatMicroShopView;
    }




    /**
     * 配置小微商户绑定APPid
     * @param subMchid 小微商户申请的商户Id
     * @param subMicroAppid 绑定服务商道公众号、小程序、APP支付等对应的APPID
     * @return
     * @throws Exception
     */
    public WechatMicroShopView configMicroShopAppid(String subMchid,String subMicroAppid)throws Exception{
        WechatMicroShopView wechatMicroShopView = null;
        String url = WechatConstants.CONFIG_MICROSHOP_PAYMENT;
        Map<String,String> params = new HashMap<>();
        params.put("appid",this.getAppid());
        params.put("mch_id",this.getMchid());
        params.put("sub_mch_id",subMchid);
        params.put("sub_appid",subMicroAppid);
        String signString = WechatEncryptHelper.getSignByMD5(params,this.getPaymentKey());
        params.put("sign", signString);
        String httpResult = this.getHttpSSLHelper().doPost4XML(url, StringHelper.mapToXml(params)).getResult();
        logger.info("小微商户配置绑定APPID请求结果："+httpResult);
        Map<String,String> resultMap = StringHelper.xmlToMap(httpResult);
        if(null!=resultMap && resultMap.keySet().contains("return_code")&&resultMap.get("return_code").equals(WechatConstants.SUCCESS)){
            wechatMicroShopView = new WechatMicroShopView();
            wechatMicroShopView.setReturnCode(WechatConstants.SUCCESS);
            wechatMicroShopView.setResultCode(resultMap.get("result_code"));
            if(resultMap.get("result_code").equals(WechatConstants.FAIL)){
                wechatMicroShopView.setErrCode(resultMap.get("err_code"));
                wechatMicroShopView.setErrCodeDes(resultMap.get("err_code_des"));
            }

        }
        return wechatMicroShopView;
    }



    /**
     * 获取小微商户支付配置信息
     * @param subMchid 小微商户申请的商户Id
     * @param subMicroAppid 绑定服务商道公众号、小程序、APP支付等对应的APPID
     * @return
     * @throws Exception
     */
    public WechatMicroShopView getMicroShopConfig(String subMchid,String subMicroAppid)throws Exception{
        WechatMicroShopView wechatMicroShopView = null;
        String url = WechatConstants.GET_MICROSHOP_CONFIG;
        Map<String,String> params = new HashMap<>();
        params.put("appid",this.getAppid());
        params.put("mch_id",this.getMchid());
        params.put("sub_mch_id",subMchid);
        String signString = WechatEncryptHelper.getSignByMD5(params,this.getPaymentKey());
        params.put("sign", signString);
        String httpResult = this.getHttpSSLHelper().doPost4XML(url, StringHelper.mapToXml(params)).getResult();
        logger.info("获取小微商户支付配置信息请求结果："+httpResult);
        Map<String,String> resultMap = StringHelper.xmlToMap(httpResult);
        if(null!=resultMap && resultMap.keySet().contains("return_code")&&resultMap.get("return_code").equals(WechatConstants.SUCCESS)){
            wechatMicroShopView = new WechatMicroShopView();
            wechatMicroShopView.setReturnCode(WechatConstants.SUCCESS);
            wechatMicroShopView.setResultCode(resultMap.get("result_code"));
            if(resultMap.get("result_code").equals(WechatConstants.FAIL)){
                wechatMicroShopView.setErrCode(resultMap.get("err_code"));
                wechatMicroShopView.setErrCodeDes(resultMap.get("err_code_des"));
            }else if(resultMap.get("result_code").equals(WechatConstants.SUCCESS)){
                wechatMicroShopView.setAppidConfigList(resultMap.get("appid_config_list"));
                wechatMicroShopView.setJsapiPathPist(resultMap.get("jsapi_path_list"));
            }

        }
        return wechatMicroShopView;
    }

    public static WechatMicroShopUtils getWechatMicroShopUtils() {
        return wechatMicroShopUtils;
    }

    public static void setWechatMicroShopUtils(WechatMicroShopUtils wechatMicroShopUtils) {
        WechatMicroShopUtils.wechatMicroShopUtils = wechatMicroShopUtils;
    }

    public String getCertPath() {
        return certPath;
    }

    public void setCertPath(String certPath) {
        this.certPath = certPath;
    }

    public String getMchid() {
        return mchid;
    }

    public void setMchid(String mchid) {
        this.mchid = mchid;
    }

    public String getPaymentKey() {
        return paymentKey;
    }

    public void setPaymentKey(String paymentKey) {
        this.paymentKey = paymentKey;
    }

    public String getApiKey() {
        return apiKey;
    }

    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }

    public HttpSSLHelper getHttpSSLHelper() {
        return httpSSLHelper;
    }

    public void setHttpSSLHelper(HttpSSLHelper httpSSLHelper) {
        this.httpSSLHelper = httpSSLHelper;
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }
}
